﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Reflection;

using InterfacesInstanceClustering;
using InterfacesTransformation;
using DTO;
using DAL;

namespace InstanceClusteringHost
{
    public partial class InstanceClusteringHost : UserControl, IInstanceClusteringHost
    {
        public InstanceClusteringHost()
        {
            InitializeComponent();
            this.textBox_OutputDes.Text = Global.outputDes;
        }

        #region Keyword Filter
        public void FeedBack(string feedBackStr, IKeywordFilter pluginInterface)
        {
            //...
        }

        private Types.AvailableKeywordFilterPluginCollection availKFPluginList = new Types.AvailableKeywordFilterPluginCollection();
        private List<bool> activeKFPlugins = new List<bool>();

        public Types.AvailableKeywordFilterPluginCollection AvailKFPluginList
        {
            get { return availKFPluginList; }
            set { availKFPluginList = value; }
        }

        private int AddKFPlugin(string fileName)
        {
            FileInfo fi = new FileInfo(fileName);
            int countNewPlugin = 0;
            if (fi.Extension.Equals(".dll"))
            {
                try
                {
                    Assembly pluginAssembly = Assembly.LoadFrom(fileName);

                    foreach (Type pluginType in pluginAssembly.GetTypes())
                    {
                        if (pluginType.IsPublic)
                        {
                            if (!pluginType.IsAbstract)
                            {
                                Type typeInterface = pluginType.GetInterface("InterfacesInstanceClustering.IKeywordFilter", true);

                                if (typeInterface != null)
                                {
                                    Types.AvailableKeywordFilterPlugin newPlugin = new Types.AvailableKeywordFilterPlugin();

                                    newPlugin.MyAssemblyPath = fileName;

                                    newPlugin.MyInstance = (IKeywordFilter)Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString()));

                                    newPlugin.MyInstance.PluginHost = this;

                                    //newPlugin.MyInstance.Initialize();

                                    // check if the new plugin does exist
                                    bool isExist = false;
                                    foreach (Types.AvailableKeywordFilterPlugin plugin in availKFPluginList)
                                    {
                                        if (plugin.MyInstance.PluginName.Equals(newPlugin.MyInstance.PluginName))
                                        {
                                            isExist = true;
                                        }
                                    }
                                    // add new plugin if 
                                    if (isExist == false)
                                    {
                                        this.availKFPluginList.Add(newPlugin);
                                        this.activeKFPlugins.Add(false);
                                        countNewPlugin++;
                                    }

                                    newPlugin = null;
                                }

                                typeInterface = null;
                            }
                        }
                    }

                    pluginAssembly = null;
                }
                catch
                {
                    MessageBox.Show("Loading plugin dll failed!");
                }
            }

            return countNewPlugin;
        }

        public int AddKFPlugins(string[] fileNames)
        {
            int countNewPlugin = 0;
            foreach (string file in fileNames)
            {
                countNewPlugin += AddKFPlugin(file);
            }

            if (availKFPluginList.Count == 0)
            {
                MessageBox.Show("No plugin was load!");
            }

            return countNewPlugin;
        }

        public void CloseAllWFPlugin()
        {
            foreach (Types.AvailableKeywordFilterPlugin plugin in availKFPluginList)
            {
                plugin.MyInstance.PluginDispose();

                plugin.MyInstance = null;
            }

            availKFPluginList.Clear();
        }

        public void FindKFPlugins(string path)
        {
            availKFPluginList.Clear();

            foreach (string file in Directory.GetFiles(path))
            {
                FileInfo fileInfo = new FileInfo(file);

                if (fileInfo.Extension.Equals(".dll"))
                {
                    this.AddKFPlugin(file);
                }
            }
        }

        public void FindKFPlugins()
        {
            FindKFPlugins(AppDomain.CurrentDomain.BaseDirectory);
        }

        public void LoadKFPlugins()
        {
            openFileDialog_LoadPlugin.Multiselect = true;
            openFileDialog_LoadPlugin.Filter = "Plugin (*.dll) |*.dll";
            openFileDialog_LoadPlugin.InitialDirectory = Directory.GetCurrentDirectory();
            if (openFileDialog_LoadPlugin.ShowDialog() == DialogResult.OK)
            {
                if (openFileDialog_LoadPlugin.FileNames.Length != 0)
                {
                    AddKFPlugins(openFileDialog_LoadPlugin.FileNames);
                }
            }
        }
        #endregion

        #region Cluster Tool
        public void FeedBack(string feedBackStr, IClustering pluginInterface)
        {
            //...
        }

        private Types.AvailableClusterToolPluginCollection availClusterPluginList = new Types.AvailableClusterToolPluginCollection();

        public Types.AvailableClusterToolPluginCollection AvailXCPluginList
        {
            get { return availClusterPluginList; }
            set { availClusterPluginList = value; }
        }

        private void AddClusterPlugin(string fileName)
        {
            FileInfo fi = new FileInfo(fileName);
            if (fi.Extension.Equals(".dll"))
            {
                try
                {
                    Assembly pluginAssembly = Assembly.LoadFrom(fileName);

                    foreach (Type pluginType in pluginAssembly.GetTypes())
                    {
                        if (pluginType.IsPublic)
                        {
                            if (!pluginType.IsAbstract)
                            {
                                Type typeInterface = pluginType.GetInterface("InterfacesInstanceClustering.IClustering", true);

                                if (typeInterface != null)
                                {
                                    Types.AvailableClusterToolPlugin newPlugin = new Types.AvailableClusterToolPlugin();

                                    newPlugin.MyAssemblyPath = fileName;

                                    newPlugin.MyInstance = (IClustering)Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString()));

                                    newPlugin.MyInstance.PluginHost = this;

                                    newPlugin.MyInstance.Initialize();

                                    this.availClusterPluginList.Clear(); // Make sure there is just only one plugin at time
                                    this.availClusterPluginList.Add(newPlugin);

                                    newPlugin = null;
                                }

                                typeInterface = null;
                            }
                        }
                    }

                    pluginAssembly = null;
                }
                catch
                {
                    MessageBox.Show("Loading plugin dll failed!");
                }
            }
        }

        public void AddClusterPlugins(string[] fileNames)
        {
            foreach (string file in fileNames)
            {
                AddClusterPlugin(file);
            }

            if (availClusterPluginList.Count == 0)
            {
                MessageBox.Show("No plugin was load!");
            }
        }

        public void CloseAllXCPlugin()
        {
            foreach (Types.AvailableClusterToolPlugin plugin in availClusterPluginList)
            {
                plugin.MyInstance.PluginDispose();

                plugin.MyInstance = null;
            }

            availClusterPluginList.Clear();
        }

        public void FindClusterPlugins(string path)
        {
            availClusterPluginList.Clear();

            foreach (string file in Directory.GetFiles(path))
            {
                FileInfo fileInfo = new FileInfo(file);

                if (fileInfo.Extension.Equals(".dll"))
                {
                    this.AddClusterPlugin(file);
                }
            }
        }

        public void FindClusterPlugins()
        {
            FindClusterPlugins(AppDomain.CurrentDomain.BaseDirectory);
        }

        public void LoadClusterPlugins()
        {
            openFileDialog_LoadPlugin.Multiselect = false;
            openFileDialog_LoadPlugin.Filter = "Plugin (*.dll) |*.dll";
            openFileDialog_LoadPlugin.InitialDirectory = Directory.GetCurrentDirectory();
            if (openFileDialog_LoadPlugin.ShowDialog() == DialogResult.OK)
            {
                if (openFileDialog_LoadPlugin.FileName != string.Empty)
                {
                    string selectedFile = openFileDialog_LoadPlugin.FileName;

                    this.availClusterPluginList.Clear();
                    AddClusterPlugin(openFileDialog_LoadPlugin.FileName);
                }
            }
        }
        #endregion

        #region Vectorizer
        public void FeedBack(string feedBackStr, IVectorizer pluginInterface)
        {
            //...
        }

        private Types.AvailableVectorizerPluginCollection availVectorizerPluginList = new Types.AvailableVectorizerPluginCollection();

        public Types.AvailableVectorizerPluginCollection AvailVectorizerPluginList
        {
            get { return availVectorizerPluginList; }
            set { availVectorizerPluginList = value; }
        }

        private void AddVectorizerPlugin(string fileName)
        {
            FileInfo fi = new FileInfo(fileName);
            if (fi.Extension.Equals(".dll"))
            {
                try
                {
                    Assembly pluginAssembly = Assembly.LoadFrom(fileName);

                    foreach (Type pluginType in pluginAssembly.GetTypes())
                    {
                        if (pluginType.IsPublic)
                        {
                            if (!pluginType.IsAbstract)
                            {
                                Type typeInterface = pluginType.GetInterface("InterfacesInstanceClustering.IVectorizer", true);

                                if (typeInterface != null)
                                {
                                    Types.AvailableVectorizerPlugin newPlugin = new Types.AvailableVectorizerPlugin();

                                    newPlugin.MyAssemblyPath = fileName;

                                    newPlugin.MyInstance = (IVectorizer)Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString()));

                                    newPlugin.MyInstance.PluginHost = this;

                                    newPlugin.MyInstance.Initialize();

                                    this.availVectorizerPluginList.Clear(); // Make sure there is just only one plugin at time
                                    this.availVectorizerPluginList.Add(newPlugin);

                                    newPlugin = null;
                                }

                                typeInterface = null;
                            }
                        }
                    }

                    pluginAssembly = null;
                }
                catch
                {
                    MessageBox.Show("Loading plugin dll failed!");
                }
            }
        }

        public void AddVectorizerPlugins(string[] fileNames)
        {
            foreach (string file in fileNames)
            {
                AddVectorizerPlugin(file);
            }

            if (availVectorizerPluginList.Count == 0)
            {
                MessageBox.Show("No plugin was load!");
            }
        }

        public void CloseAllVectorizerPlugin()
        {
            foreach (Types.AvailableVectorizerPlugin plugin in availVectorizerPluginList)
            {
                plugin.MyInstance.PluginDispose();

                plugin.MyInstance = null;
            }

            availVectorizerPluginList.Clear();
        }

        public void FindVectorizerPlugins(string path)
        {
            availVectorizerPluginList.Clear();

            foreach (string file in Directory.GetFiles(path))
            {
                FileInfo fileInfo = new FileInfo(file);

                if (fileInfo.Extension.Equals(".dll"))
                {
                    this.AddVectorizerPlugin(file);
                }
            }
        }

        public void FindVectorizerPlugins()
        {
            FindVectorizerPlugins(AppDomain.CurrentDomain.BaseDirectory);
        }

        public void LoadVectorizerPlugin()
        {
            openFileDialog_LoadPlugin.Multiselect = false;
            openFileDialog_LoadPlugin.Filter = "Plugin (*.dll) |*.dll";
            openFileDialog_LoadPlugin.InitialDirectory = Directory.GetCurrentDirectory();
            if (openFileDialog_LoadPlugin.ShowDialog() == DialogResult.OK)
            {
                if (openFileDialog_LoadPlugin.FileName != string.Empty)
                {
                    this.availClusterPluginList.Clear();
                    AddVectorizerPlugin(openFileDialog_LoadPlugin.FileName);
                }
            }
        }
        #endregion

        #region Word Segmentor
        public void FeedBack(string feedBackStr, IWordSegmentor pluginInterface)
        {
            //...
        }

        private Types.AvailableWordSegmentorPluginCollection availWSgPluginList = new Types.AvailableWordSegmentorPluginCollection();

        public Types.AvailableWordSegmentorPluginCollection AvailWSgPluginList
        {
            get { return availWSgPluginList; }
            set { availWSgPluginList = value; }
        }

        private void AddWSgPlugin(string fileName)
        {
            FileInfo fi = new FileInfo(fileName);
            if (fi.Extension.Equals(".dll"))
            {
                try
                {
                    Assembly pluginAssembly = Assembly.LoadFrom(fileName);

                    foreach (Type pluginType in pluginAssembly.GetTypes())
                    {
                        if (pluginType.IsPublic)
                        {
                            if (!pluginType.IsAbstract)
                            {
                                Type typeInterface = pluginType.GetInterface("InterfacesTransformation.IWordSegmentor", true);

                                if (typeInterface != null)
                                {
                                    Types.AvailableWordSegmentorPlugin newPlugin = new Types.AvailableWordSegmentorPlugin();

                                    newPlugin.MyAssemblyPath = fileName;

                                    newPlugin.MyInstance = (IWordSegmentor)Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString()));

                                    newPlugin.MyInstance.PluginHost = this;

                                    newPlugin.MyInstance.Initialize();

                                    this.availWSgPluginList.Clear(); // Make sure there is just only one plugin at time
                                    this.availWSgPluginList.Add(newPlugin);

                                    newPlugin = null;
                                }

                                typeInterface = null;
                            }
                        }
                    }

                    pluginAssembly = null;
                }
                catch
                {
                    MessageBox.Show("Loading plugin dll failed!");
                }
            }
        }

        public void AddWSgPlugins(string[] fileNames)
        {
            foreach (string file in fileNames)
            {
                AddWSgPlugin(file);
            }

            if (availWSgPluginList.Count == 0)
            {
                MessageBox.Show("No plugin was load!");
            }
        }

        public void CloseAllWSgPlugin()
        {
            foreach (Types.AvailableWordSegmentorPlugin plugin in availWSgPluginList)
            {
                plugin.MyInstance.PluginDispose();

                plugin.MyInstance = null;
            }

            availWSgPluginList.Clear();
        }

        public void FindWSgPlugins(string path)
        {
            availWSgPluginList.Clear();

            foreach (string file in Directory.GetFiles(path))
            {
                FileInfo fileInfo = new FileInfo(file);

                if (fileInfo.Extension.Equals(".dll"))
                {
                    this.AddWSgPlugin(file);
                }
            }
        }

        public void FindWSgPlugins()
        {
            FindWSgPlugins(AppDomain.CurrentDomain.BaseDirectory);
        }

        public void LoadWSgPlugins()
        {
            openFileDialog_LoadPlugin.Multiselect = false;
            openFileDialog_LoadPlugin.Filter = "Plugin (*.dll) |*.dll";
            openFileDialog_LoadPlugin.InitialDirectory = Directory.GetCurrentDirectory();
            if (openFileDialog_LoadPlugin.ShowDialog() == DialogResult.OK)
            {
                if (openFileDialog_LoadPlugin.FileName != string.Empty)
                {
                    string selectedFile = openFileDialog_LoadPlugin.FileName;

                    this.availClusterPluginList.Clear();
                    AddWSgPlugin(openFileDialog_LoadPlugin.FileName);
                }
            }
        }
        #endregion

        #region Filter Keyword Plugin Functions
        /// <summary>
        /// Filter keyword with current Keyword Filter Plugins
        /// </summary>
        /// <param name="keyword">The keyword which will be filtered</param>
        /// <returns>True if it gets through the filter, false otherwise</returns>
        public bool FilterKeyword(DTO.Keyword keyword)
        {
            bool result = true;

            for (int i = 0; i < availKFPluginList.Count; i++)
            {
                if (activeKFPlugins[i] == true)
                {
                    try
                    {
                        result &= availKFPluginList.Get(i).MyInstance.IsDesirableKeyword(keyword);                        
                    }
                    catch (Exception ex)
                    {
                        throw ex;
                    }
                }
            }

            return result;
        }

        /// <summary>
        /// Filter keywords with current Webpage Filter Plugins
        /// </summary>
        /// <param name="keywords">The keywords which will be filtered</param>
        /// <returns>List of keyword which got through filters</returns>
        public List<Keyword> FilterKeywords(DTO.Keyword[] keywords)
        {
            List<Keyword> result = new List<Keyword>();

            foreach (DTO.Keyword kw in keywords)
            {
                if (FilterKeyword(kw))
                {
                    result.Add(kw);
                }
            }

            return result;
        }
        /// <summary>
        /// Make common terms
        /// </summary>
        /// <returns>The common keyword list</returns>
        public List<Keyword> MakeCommonTerms()
        {
            List<Keyword> commonTerms = new List<Keyword>();
            if (Global.metaSource == true)
            {
                commonTerms.AddRange(WebpageDAL.GetAllMetaKeywords());
            }

            if (Global.titleSource == true)
            {
                if (Global.metaSource == false)
                {
                    commonTerms.AddRange(WebpageDAL.GetAllTitleKeywords());
                }
                else
                {
                    List<Keyword> temp = WebpageDAL.GetAllTitleKeywords();
                    foreach (Keyword keyword in temp)
                    {                        
                        int i = 0;
                        int n = commonTerms.Count;
                        for (i = 0; i < n; i++)
                        {                        
                            if (keyword.KeywordText.Equals(commonTerms[i].KeywordText))
                            {
                                commonTerms[i].Score += keyword.Score;                                
                                break;
                            }
                        }

                        if (i == n - 1)
                        {
                            commonTerms.Add(keyword);
                        }
                    }
                }
            }

            commonTerms = FilterKeywords(commonTerms.ToArray());
            return commonTerms;
        }
        #endregion

        #region Cluster Tool Plugin Functions
        /// <summary>
        /// Cluster all vectors from input file & write the output result file
        /// </summary>
        public void Cluster()
        {
            if (this.availClusterPluginList.Count == 1)
            {
                try
                {
                    this.availClusterPluginList.Get(0).MyInstance.Cluster();
                }
                catch
                {
                    MessageBox.Show("Please set the cluster parameters!");
                }
            }
            else
            {
                MessageBox.Show("You have not chosen a Cluster Tool yet!");
            }
        } 
        #endregion

        #region Vectorizer Plugin Functions
        /// <summary>
        /// Vectorize a webpage
        /// </summary>
        /// <param name="webpage">The webpage which will be vectorized</param>
        /// <returns>The vector of webpage</returns>
        public Vector VectorizeWebpage(Webpage webpage)
        {
            try
            {
                //WebpageDAL.GetAllMetaKeywords();
                //WebpageDAL.GetAllTitleKeywords();
                //
                // Make split webtag list
                List<Webtag> splitWebtagList = WebtagDAL.GetTags(webpage.ID);
                List<string> tempSegmentedStringList = new List<string>();
                foreach (Webtag curWebtag in splitWebtagList)
                {
                    tempSegmentedStringList.Add(curWebtag.Text);
                }
                tempSegmentedStringList = new List<string>(availWSgPluginList.Get(0).MyInstance.Segment(tempSegmentedStringList));
                for (int i = 0; i < splitWebtagList.Count; i++)
                {
                    splitWebtagList[i].Text = tempSegmentedStringList[i];
                }
                // Make list of meta keyword string
                List<Keyword> metaKeywords = WebpageDAL.GetKeywordsList(webpage.ID);
                List<string> metaKeywordStr = new List<string>();
                foreach (Keyword keyword in metaKeywords)
                {
                    metaKeywordStr.Add(keyword.KeywordText);
                }
                // Make split webpage title
                string splitWebpageTitle = availWSgPluginList.Get(0).MyInstance.Segment(webpage.Title);
                //
                List<string> annotatedKeywords = new List<string>();
                if (Global.metaSource == true)
                {
                    annotatedKeywords.AddRange(metaKeywordStr);
                }

                if (Global.titleSource == true)
                {
                    List<Keyword> temp = WebpageDAL.GetTitleKeywordsList(webpage.ID);
                    foreach (Keyword keyword in temp)
                    {
                        annotatedKeywords.Add(keyword.KeywordText);
                    }
                }

                // Make vector
                return availVectorizerPluginList.Get(0).MyInstance.Vectorize(webpage.ID
                    , annotatedKeywords
                    , splitWebtagList
                    , metaKeywordStr
                    , splitWebpageTitle
                    , Global.commonTerms);
            }
            catch (Exception ex)
            {
                throw ex;
            }            
        }
        /// <summary>
        /// Vectorize all webpage in the database
        /// </summary>
        /// <returns>List of vectors</returns>
        public List<Vector> VectorizeAllWebpage()
        {
            try
            {
                List<Webpage> webpageList = WebpageDAL.GetWebpages();

                if (availVectorizerPluginList.Count != 1)
                {
                    throw new Exception("You have not add Vectorizer Plugin!");
                }
                else if (availWSgPluginList.Count != 1)
                {
                    throw new Exception("You have not add Word Segmenter Plugin!");
                }
                else
                {
                    try
                    {
                        List<Vector> allVectors = new List<Vector>();
                        foreach (Webpage webpage in webpageList)
                        {
                            allVectors.Add(VectorizeWebpage(webpage));
                        }

                        return allVectors;
                    }
                    catch (Exception ex)
                    {
                        throw ex;
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }        
        #endregion

        #region Word Segmentor Plugin Functions
        /// <summary>
        /// Segment a string using the added plugin
        /// </summary>
        /// <param name="inputStr">The string which will be segmented</param>
        /// <returns>The segmented string</returns>
        public string SegmentString(string inputStr)
        {
            if (this.availWSgPluginList.Count != 0)
            {
                try
                {
                    return availWSgPluginList.Get(0).MyInstance.Segment(inputStr);
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }
            else
            {
                throw new Exception("Word Segmentor Plugin is not loaded!");
            }
        }
        #endregion

        #region GUI Event Handler
        private void button_WSBrowse_Click(object sender, EventArgs e)
        {
            LoadWSgPlugins();
            this.AddWSgPlugins(openFileDialog_LoadPlugin.FileNames);

            if (availWSgPluginList.Count != 0)
            {
                this.textBox_WSPlugin.Text = availWSgPluginList.Get(0).MyInstance.PluginName;
                this.groupBox_WSParameter.Controls.Clear();
                availWSgPluginList.Get(0).MyInstance.PluginUserControl.Dock = DockStyle.Fill;
                this.groupBox_WSParameter.Controls.Add(availWSgPluginList.Get(0).MyInstance.PluginUserControl);
            }
        }

        private void button_ODBrowse_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog folderBrowserDlg = new FolderBrowserDialog();
            folderBrowserDlg.SelectedPath = Directory.GetCurrentDirectory();

            if (folderBrowserDlg.ShowDialog() == DialogResult.OK)
            {
                this.textBox_OutputDes.Text = folderBrowserDlg.SelectedPath;
                Global.outputDes = folderBrowserDlg.SelectedPath;
            }
        }

        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            Global.metaSource = checkBox1.Checked;
        }

        private void checkBox2_CheckedChanged(object sender, EventArgs e)
        {
            Global.titleSource = checkBox2.Checked;
        }

        private void button_LoadFilter_Click(object sender, EventArgs e)
        {
            LoadKFPlugins();

            if (availKFPluginList.Count > 0) 
            {
                this.checkedListBox_KeywordFilter.Items.Clear();

                foreach (Types.AvailableKeywordFilterPlugin plugin in availKFPluginList)
                {
                    this.checkedListBox_KeywordFilter.Items.Add(plugin.MyInstance.PluginName);
                }
            }
        }

        private void button_ClearePlugin_Click(object sender, EventArgs e)
        {
            this.checkedListBox_KeywordFilter.Items.Clear();
            this.availKFPluginList.Clear();
            this.activeKFPlugins.Clear();
        }

        private void checkedListBox_KeywordFilter_SelectedValueChanged(object sender, EventArgs e)
        {
            if (this.checkedListBox_KeywordFilter.SelectedIndex >= 0)
            {
                this.richTextBox_PluginDetail.Text = this.availKFPluginList.Get(this.checkedListBox_KeywordFilter.SelectedIndex).MyInstance.PluginDescription;
            }
        }

        private void button_VectorSet_Click(object sender, EventArgs e)
        {
            LoadVectorizerPlugin();

            if (availVectorizerPluginList.Count != 0)
            {
                this.textBox_Vectorizer.Text = availVectorizerPluginList.Get(0).MyInstance.PluginName;
                this.groupBox_VectorParameters.Controls.Clear();
                availVectorizerPluginList.Get(0).MyInstance.PluginUserControl.Dock = DockStyle.Fill;
                this.groupBox_VectorParameters.Controls.Add(availVectorizerPluginList.Get(0).MyInstance.PluginUserControl);
            }
        }


        private void button_ClusterSet_Click(object sender, EventArgs e)
        {
            this.LoadClusterPlugins();
            if (availClusterPluginList.Count != 0)
            {
                Types.AvailableClusterToolPlugin plugin = availClusterPluginList.Get(0);
                this.textBox_ClusterPlugin.Text = plugin.MyInstance.PluginName;
                this.groupBox_ClusterParameter.Controls.Clear();
                plugin.MyInstance.PluginUserControl.Dock = DockStyle.Fill;                
                // Tricky
                plugin.MyInstance.PluginUserControl.OutputClusterPath = Global.outputDes;
                plugin.MyInstance.PluginUserControl.textBox_OutputClusterFile.Text = Global.outputDes;
                plugin.MyInstance.PluginUserControl.textBox_InputVectorFile.Text = Global.outputDes + @"\" + "VectorOutput.txt";
                plugin.MyInstance.PluginUserControl.InputVectorFile = Global.outputDes + @"\" + "VectorOutput.txt";
                //
                this.groupBox_ClusterParameter.Controls.Add(plugin.MyInstance.PluginUserControl);
            }
        }

        private void button_ICRun_Click(object sender, EventArgs e)
        {
            try
            {
                // Make common terms
                Global.commonTerms.Clear();
                List<Keyword> commonTermList = MakeCommonTerms();
                foreach (Keyword keyword in commonTermList)
                {
                    Global.commonTerms.Add(keyword.KeywordText);
                }
                Keyword.ToKeywordFile(commonTermList, Global.outputDes + @"\" + "CommonTermOutput.txt");
                // Vectorizing
                Vector.ToVectorFile(VectorizeAllWebpage(), Global.outputDes + @"\" + "VectorOutput.txt");
                // Clustering
                Cluster();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        } 
        #endregion

        private void checkedListBox_KeywordFilter_ItemCheck(object sender, ItemCheckEventArgs e)
        {            
            int i = this.checkedListBox_KeywordFilter.SelectedIndex;
            this.activeKFPlugins[i] = !checkedListBox_KeywordFilter.GetItemChecked(i);
            if (activeKFPlugins[i] == true)
            {
                this.availKFPluginList.Get(i).MyInstance.Initialize();
            }
        }

        private void button_Export2XML_Click(object sender, EventArgs e)
        {

        }

        private void groupBox_WSParameter_Enter(object sender, EventArgs e)
        {

        }
    }
    
    namespace Types
    {
        #region Cluster Tool Types
        public class AvailableClusterToolPlugin
        {
            private IClustering myInstance = null;

            public IClustering MyInstance
            {
                get { return myInstance; }
                set { myInstance = value; }
            }

            private string myAssemblyPath = string.Empty;

            public string MyAssemblyPath
            {
                get { return myAssemblyPath; }
                set { myAssemblyPath = value; }
            }

        }

        public class AvailableClusterToolPluginCollection : System.Collections.CollectionBase
        {
            public void Add(Types.AvailableClusterToolPlugin plugin)
            {
                this.List.Add(plugin);
            }

            public void Remove(Types.AvailableClusterToolPlugin plugin)
            {
                this.List.Remove(plugin);
            }

            public AvailableClusterToolPlugin Get(int idx)
            {
                try
                {
                    return (AvailableClusterToolPlugin)this.List[idx];
                }
                catch (IndexOutOfRangeException indexOutOfRangeEx)
                {
                    throw indexOutOfRangeEx;
                }
            }

            public AvailableClusterToolPlugin Find(string pluginNameOrPath)
            {
                AvailableClusterToolPlugin result = null;
                foreach (AvailableClusterToolPlugin plugin in this.List)
                {
                    if ((plugin.MyInstance.PluginName.Equals(pluginNameOrPath))
                        || (plugin.MyAssemblyPath.Equals(pluginNameOrPath)))
                    {
                        result = plugin;
                        break;
                    }
                }

                return result;
            }
        }
        #endregion

        #region Keyword Filter Types
        public class AvailableKeywordFilterPlugin
        {
            private IKeywordFilter myInstance = null;

            public IKeywordFilter MyInstance
            {
                get { return myInstance; }
                set { myInstance = value; }
            }

            private string myAssemblyPath = string.Empty;

            public string MyAssemblyPath
            {
                get { return myAssemblyPath; }
                set { myAssemblyPath = value; }
            }

        }

        public class AvailableKeywordFilterPluginCollection : System.Collections.CollectionBase
        {
            public void Add(Types.AvailableKeywordFilterPlugin plugin)
            {
                this.List.Add(plugin);
            }

            public void Remove(Types.AvailableKeywordFilterPlugin plugin)
            {
                this.List.Remove(plugin);
            }

            public AvailableKeywordFilterPlugin Get(int idx)
            {
                try
                {
                    return (AvailableKeywordFilterPlugin)this.List[idx];
                }
                catch (IndexOutOfRangeException indexOutOfRangeEx)
                {
                    throw indexOutOfRangeEx;
                }
            }

            public AvailableKeywordFilterPlugin Find(string pluginNameOrPath)
            {
                AvailableKeywordFilterPlugin result = null;
                foreach (AvailableKeywordFilterPlugin plugin in this.List)
                {
                    if ((plugin.MyInstance.PluginName.Equals(pluginNameOrPath))
                        || (plugin.MyAssemblyPath.Equals(pluginNameOrPath)))
                    {
                        result = plugin;
                        break;
                    }
                }

                return result;
            }
        }
        #endregion

        #region Vectorizer Types
        public class AvailableVectorizerPlugin
        {
            private IVectorizer myInstance = null;

            public IVectorizer MyInstance
            {
                get { return myInstance; }
                set { myInstance = value; }
            }

            private string myAssemblyPath = string.Empty;

            public string MyAssemblyPath
            {
                get { return myAssemblyPath; }
                set { myAssemblyPath = value; }
            }

        }

        public class AvailableVectorizerPluginCollection : System.Collections.CollectionBase
        {
            public void Add(Types.AvailableVectorizerPlugin plugin)
            {
                this.List.Add(plugin);
            }

            public void Remove(Types.AvailableVectorizerPlugin plugin)
            {
                this.List.Remove(plugin);
            }

            public AvailableVectorizerPlugin Get(int idx)
            {
                try
                {
                    return (AvailableVectorizerPlugin)this.List[idx];
                }
                catch (IndexOutOfRangeException indexOutOfRangeEx)
                {
                    throw indexOutOfRangeEx;
                }
            }

            public AvailableVectorizerPlugin Find(string pluginNameOrPath)
            {
                AvailableVectorizerPlugin result = null;
                foreach (AvailableVectorizerPlugin plugin in this.List)
                {
                    if ((plugin.MyInstance.PluginName.Equals(pluginNameOrPath))
                        || (plugin.MyAssemblyPath.Equals(pluginNameOrPath)))
                    {
                        result = plugin;
                        break;
                    }
                }

                return result;
            }
        }
        #endregion

        #region Word Segmentor Types
        public class AvailableWordSegmentorPlugin
        {
            private IWordSegmentor myInstance = null;

            public IWordSegmentor MyInstance
            {
                get { return myInstance; }
                set { myInstance = value; }
            }

            private string myAssemblyPath = string.Empty;

            public string MyAssemblyPath
            {
                get { return myAssemblyPath; }
                set { myAssemblyPath = value; }
            }

        }

        public class AvailableWordSegmentorPluginCollection : System.Collections.CollectionBase
        {
            public void Add(Types.AvailableWordSegmentorPlugin plugin)
            {
                this.List.Add(plugin);
            }

            public void Remove(Types.AvailableWordSegmentorPlugin plugin)
            {
                this.List.Remove(plugin);
            }

            public AvailableWordSegmentorPlugin Get(int idx)
            {
                try
                {
                    return (AvailableWordSegmentorPlugin)this.List[idx];
                }
                catch (IndexOutOfRangeException indexOutOfRangeEx)
                {
                    throw indexOutOfRangeEx;
                }
            }

            public AvailableWordSegmentorPlugin Find(string pluginNameOrPath)
            {
                AvailableWordSegmentorPlugin result = null;
                foreach (AvailableWordSegmentorPlugin plugin in this.List)
                {
                    if ((plugin.MyInstance.PluginName.Equals(pluginNameOrPath))
                        || (plugin.MyAssemblyPath.Equals(pluginNameOrPath)))
                    {
                        result = plugin;
                        break;
                    }
                }

                return result;
            }
        }
        #endregion
    }
}
